/*
 * Copyright 2010-2011 Sanjay Dwivedi.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.isdinvestments.cam.domain.model;

import java.io.Serializable;
import javax.persistence.*;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;


/**
 * The <b>Customer</b>. This is the central class in domain model. It is 
 * the root of the Customer-Account-SubAccount-Portfolio-Position aggregate.
 * 
 * The Customer aggregate, and the entire domain model, is built to solve the problem
 * of Customer, Account and Portfolio. All important business rules for account management,
 * current status of the customer, accounts, portfolios, positions held in a portfolio, current value of the
 * portfolio etc. are captured in this aggregate.
 */
@Entity
public class Customer implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@SequenceGenerator(name="CUSTOMER_ID_GENERATOR", sequenceName="CUSTOMER_ID_SEQ")
	@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="CUSTOMER_ID_GENERATOR")
	private long id;

	@NotNull(message="error.customer.name.empty")
	private String name;
	
	@NotNull(message="error.customer.taxId.empty")
	@Column(name="TAX_ID")
	private String taxId;
	
	@Valid
	@Embedded 
	private Address address;
	
	@Valid
	//bi-directional many-to-one association to Account
	@OneToMany(mappedBy="customer", cascade = { CascadeType.ALL } )
//	@Basic(fetch = FetchType.EAGER)
	@Fetch(FetchMode.JOIN)
	@LazyCollection(LazyCollectionOption.FALSE)
	private Set<Account> accounts;

	//bi-directional many-to-one association to ReferenceData
    @ManyToOne
	@JoinColumn(name="CUSTOMER_TYPE")
	private CustomerType customerType;

    public Customer() {
    }

	public long getId() {
		return this.id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Address getAddress() {
		return address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public String getTaxId() {
		return this.taxId;
	}

	public void setTaxId(String taxId) {
		this.taxId = taxId;
	}

	public Set<Account> getAccounts() {
		return this.accounts;
	}

	public void setAccounts(Set<Account> accounts) {
		this.accounts = accounts;
	}
	
	public CustomerType getCustomerType() {
		return this.customerType;
	}

	public void setCustomerType(CustomerType customerType) {
		this.customerType = customerType;
	}
	
	//---- Business Functions -------------------------------------------------
	
	public void addAccount(Account account) {
		
	}
	
	public void closeAccount(Long accountId) {
		
	}
	
	public void updateAccount(Account account) {
		
	}
	
	public List<Account> getAllAccounts() {
		
		return new ArrayList<Account>();
		
	}
	
	public void addSubAccount(Long accountId, SubAccount subAccount) {
		
	}
	
	public void closeSubAccount(Long subAccountId) {
		
	}
	
	public void updateAccount(SubAccount subAccount) {
		
	}
	
	public List<SubAccount> getAllSubAccounts() {
		return new ArrayList<SubAccount>();
	}
	
}